package by.airlanterns.web;

import by.airlanterns.dto.User;
import by.airlanterns.dto.UserOrder;
import by.airlanterns.dto.request.OrderRequest;
import by.airlanterns.dto.response.OrderResponse;
import by.airlanterns.service.LanternService;
import by.airlanterns.service.OrderService;
import by.airlanterns.service.UserService;
import com.google.gson.Gson;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.encoding.Md5PasswordEncoder;
import org.springframework.security.authentication.encoding.PasswordEncoder;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.mail.*;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.*;

/**
 * Created by IntelliJ IDEA.
 * User: Sergey
 * Date: 31.01.13
 * Time: 9:04
 * To change this template use File | Settings | File Templates.
 */
@Controller
@RequestMapping(value = "order")
public class OrderController extends BaseController {

    @Autowired
    private UserService userService;

    @Autowired
    private OrderService orderService;

    @Autowired
    private LanternService lanternService;
    private List<UserOrder> userOrders;

    private static final int TO_USER = 1;
    private static final int TO_ADMIN = 2;

    @RequestMapping(value = "make_order", method = RequestMethod.POST)
    private
    @ResponseBody
    OrderResponse makeOrder(HttpServletRequest request, HttpServletResponse response) {
        String orderString = request.getParameter("orders");
        Gson gson = new Gson();
        OrderRequest orderRequest = gson.fromJson(orderString, OrderRequest.class);
        if (getCurrentUser().getLogin() != null && !getCurrentUser().getLogin().equals("")) {
            userOrders = new ArrayList<UserOrder>();
            addOrders(orderRequest.getUserOrders(), getCurrentUser());
            try {
                sendEmail(getCurrentUser(), userOrders, TO_USER);
                sendEmail(getCurrentUser(), userOrders, TO_ADMIN);
            } catch (Exception e) {
                e.printStackTrace();
            }
            OrderResponse orderResponse = new OrderResponse();
            orderResponse.setErrorCode(0);
            orderResponse.setErrorMessage("");
            return orderResponse;
        } else {
            String email = request.getParameter("email");
            String phone = request.getParameter("phone");

            String login = email.substring(0, email.indexOf("@"));
            Random r = new Random(Calendar.getInstance().getTimeInMillis());

            String password = "_" + login + "_" + r.nextInt(100);   //TODO send this password to user
            System.out.print("Password =" + password);
            PasswordEncoder encoder = new Md5PasswordEncoder();
            String hashedPass = encoder.encodePassword(password, null);

            User user = new User();

            user.setLogin(login);
            user.setEmail(email);
            user.setLevel(ROLE_USER);
            user.setPassword(hashedPass);
            user.setPhone(phone);
            user.setToken("");

            int resultCode = userService.saveUser(user);
            if (resultCode == UserService.STATUS_OK) {
                userOrders = new ArrayList<UserOrder>();
                addOrders(orderRequest.getUserOrders(), user);
                try {
                    sendEmail(user, userOrders, TO_USER);
                    sendEmail(user, userOrders, TO_ADMIN);
                } catch (Exception e) {
                    e.printStackTrace();
                }

                OrderResponse orderResponse = new OrderResponse();
                orderResponse.setErrorCode(0);
                orderResponse.setErrorMessage("");
                return orderResponse;
            } else {
                OrderResponse orderResponse = new OrderResponse();
                orderResponse.setErrorCode(resultCode);
                orderResponse.setErrorMessage("Данный Email адрес уже используется. Для работы в системе, авторизируйтесь!");
                return orderResponse;
            }
        }
    }

    private void addOrders(List<UserOrder> orders, User user) {
        for (UserOrder order : orders) {
            order.setLantern(lanternService.findById(order.getLantern().getIdLantern()));
            order.setUser(user);
            order.setDate(new Date());
            orderService.saveOrder(order);
            userOrders.add(order);
        }
    }

    public void sendEmail(final User user, List<UserOrder> orders, int type) throws MessagingException, AuthenticationFailedException {
        boolean debug = false;

        //Set the host smtp address
        Properties props = new Properties();
        props.put("mail.transport.protocol", "smtp");
        props.put("mail.smtp.host", "localhost");
        Authenticator auth = new SMTPAuthenticator();
        Session session = Session.getDefaultInstance(props, auth);

        session.setDebug(debug);
        Transport transport = session.getTransport();
        MimeMessage message = new MimeMessage(session);
        message.setSubject("MySky.by - New order");
        message.setFrom(new InternetAddress("postmaster@mysky.by"));
        StringBuilder sb = new StringBuilder();

        //generate table
        sb.append("<table>");
        for (UserOrder order : orders) {
            sb.append("<tr><td>" + order.getLantern().getDescription() + "</td>" +
                    "<td>" + order.getAmount() + "</td>" +
                    "<td>" + order.getLantern().getPrice() + "</td></tr>");
        }
        sb.append("</table>");
        switch (type) {

            case TO_USER:
                message.setContent("<head><meta http-equiv='Content-Type' content='text/html; charset=UTF-8'/>" +
                        "</head>" +
                        "<div style='width:400px; background: #f6f7f7;" +
                        "border: 1px dashed #cbcccc;'><div><h1 style='color: #a1a1a1;" +
                        "text-shadow: 1px 1px 1px #fff;" +
                        "font-size: 25px;" +
                        "padding: 0;" +
                        "margin: 10px;" +
                        "display: inline'>Здравствуйте!</h1><p style='margin:10px;'>Это письмо было сгенерированно" +
                        " автоматически, поэтому не стоит отвечать на него!<br/>" +
                        "На сайте по адресу <a href ='http://mysky.by'>MySky.by</a>" +
                        " пользователь с вашим E-mail адресом воспользовался функцией оформления заказа. <br/>" +
                        "Вы заказали<br>" + sb.toString() + "</p></div></div>"
                        , "text/html;charset=\"UTF-8\"");
                break;
            case TO_ADMIN:
                message.setContent("<head><meta http-equiv='Content-Type' content='text/html; charset=UTF-8'/></head>" +
                        "<h1>Здравствуйте!</h1><p>Это письмо было сгенерированно" +
                        " автоматически, поэтому не стоит отвечать на него!<br/>" +
                        "На сайте по адресу <a href ='http://mysky.by'>MySky.by</a>" +
                        " пользователь " + user.getEmail() + " и телефоном " + user.getPhone() + ". <br/>" +
                        "Пользователь заказал:<br/>"
                        + sb.toString()
                        , "text/html;charset=\"UTF-8\"");

                break;
        }

        message.addRecipient(Message.RecipientType.TO, new InternetAddress(user.getEmail()));
        transport.connect();
        transport.sendMessage(message, message.getRecipients(Message.RecipientType.TO));
        transport.close();
    }

    private class SMTPAuthenticator extends javax.mail.Authenticator {

        public PasswordAuthentication getPasswordAuthentication() {
            String username = "ssadovnikov@elilink.com";
            String password = "ssadovnikov";
            return new PasswordAuthentication(username, password);
        }
    }

}
